package com.eqxiu.ieditor.api.controller.weixin;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.eqxiu.ieditor.api.controller.BaseApiController;
import com.eqxiu.ieditor.api.controller.weixin.doc.WxUserDoc;
import com.eqxiu.ieditor.commons.web.MsgCode;
import com.eqxiu.ieditor.commons.web.ResultData;
import com.eqxiu.ieditor.utils.WeiXinUtil;
import com.eqxiu.ieditor.weixin.api.WeiXinServiceApi;
import com.eqxiu.ieditor.weixin.dto.QrTicket;
import com.eqxiu.user.api.UserApi;

import eqxiu.passport.sdk.utils.CookieUtils;

/**
 * 
 * @description 易企秀登录关注公众号
 * @author ranger
 * @date Sep 13, 2017
 */
@RestController
public class WxUserController implements WxUserDoc, BaseApiController {
    private final Logger logger = LoggerFactory.getLogger(WxUserController.class);

    @Autowired
    private StringRedisTemplate redisTemplate;

    static final String USER_CACHE_COOKIE_NAME = "ie_wx_encode_id";
    static final String WX_LOGIN_COOKIE_NAME = "wxloginqrkey";;

    @Autowired
    private WeiXinServiceApi weiXinServiceApi;

    @Autowired
    private UserApi userApi;

    private final String QRLOGIN_PREFIX = "IE:QR:LOGIN_KEY";

    /**
     * 登陆状态保持是通过cookie进行的.redis做 1.未关注,redis key {@link WX_LOGIN_COOKIE_NAME},Value是以http开头的 2.关注后,redis key
     * {@link WX_LOGIN_COOKIE_NAME},Value改写为encodeId|qrurl,更节省内存
     * 
     */
    @GetMapping("/api/wx/qrlogin")
    public ResultData qrlogin(HttpServletRequest req, HttpServletResponse resp) {
        Map<String, Object> map = new HashMap<>();

        String wxloginqrvalue;
        final Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            wxloginqrvalue = CookieUtils.getCookie(req, WX_LOGIN_COOKIE_NAME, "");
            if (wxloginqrvalue != null) {
                String qrkeyValUserApi = userApi.getCacheForHandleEvent(wxloginqrvalue);
                String qrkeyVal = redisTemplate.opsForValue().get(wxloginqrvalue);
                if (qrkeyVal != null || qrkeyValUserApi != null) {
                    logger.info("this is qrkeyVal={}", qrkeyVal);
                    if (qrkeyVal.startsWith("http")) {
                        map.put("qrurl", qrkeyVal);
                        return success().setMap(map).setMsg("non subscribe or auth from wx");
                    } else {
                        String[] pairs = qrkeyVal.split("\\|");
                        map.put("encodeId", pairs[0]);
                        map.put("qrurl", pairs[1]);
                        CookieUtils.getCookie(req, resp, WX_LOGIN_COOKIE_NAME, "", true);
                        return success().setMap(map);
                    }
                } else {
                    CookieUtils.getCookie(req, resp, WX_LOGIN_COOKIE_NAME, "", true);
                    return fail().setCode(MsgCode.DATA_NOT_EXIST);
                }
            }
        }

        wxloginqrvalue = QRLOGIN_PREFIX + WeiXinUtil.generateNonceStr();
        final String appId = req.getParameter("appId");
        logger.info("this is appid={}", appId);
        if (StringUtils.isEmpty(appId)) {
            return fail().setCode(MsgCode.CONSTRAINT_VIOLATION).setMsg("appId not exist");
        }

        QrTicket optional = weiXinServiceApi.getUnlimitTicket(appId, wxloginqrvalue);
        //Optional<QrTicketDTO> optional = weiXinServiceApi.getUnlimitTicket(appId, wxloginqrvalue);

        if (optional == null) {
            return fail().setMsg("generate qr failed");
        }
        map.put("qrurl", optional.getUrl());
        Cookie cookie = new Cookie(WX_LOGIN_COOKIE_NAME, wxloginqrvalue);
        cookie.setMaxAge(3000);
        resp.addCookie(cookie);
        userApi.saveCacheForHandleEvent(wxloginqrvalue, optional.getUrl());
        redisTemplate.opsForValue().set(wxloginqrvalue, optional.getUrl(), 3600, TimeUnit.SECONDS);
        return success().setMap(map);
    }

    /**
     * 
     * @description 微信授权接口,通过code换取token和openid,通过token和openid换取用户信息
     * @author ranger
     * @date Aug 3, 2017
     * @modified by xxx 修改说明
     * @param req
     * @param resp
     * @throws IOException
     */
    @RequestMapping("/wx/user/info")
    public void wxAuth(@RequestParam String appId, @RequestParam String code, @RequestParam String state,
        HttpServletResponse resp) throws IOException {

        try {
            String openid = weiXinServiceApi.getOAuthOpenId(appId, code);
            String encodeId = WeiXinUtil.MD5(openid);
            // 将openId加密写入cookie
            Cookie c = new Cookie(USER_CACHE_COOKIE_NAME, encodeId);
            c.setPath("/");
            resp.addCookie(c);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 重定向到场景页面，state为前端传给微信的一个自定义参数，重定向url
        resp.sendRedirect(state);
    }

    @RequestMapping("/api/wx/user/cache")
    public ResultData getCacheWxUser(HttpServletRequest req, HttpServletResponse resp) {
        Cookie[] cookies = req.getCookies();
        if (cookies == null) {
            return fail().setCode(MsgCode.NOUSER);
        }

        String encodeId = CookieUtils.getCookie(req, USER_CACHE_COOKIE_NAME, "");

        return encodeId == null ? fail().setCode(MsgCode.NOUSER)
            : success().setObj(JSON.parseObject(redisTemplate.opsForValue().get("ie_wx_user_" + encodeId), Map.class));
    }
}
